import {
    CircleGeometry,
    DoubleSide, type Material,
    Mesh, MeshBasicMaterial,
    Vector2,
} from "three";
import type {CircleItem} from "./CircleItem.ts";
import {PointGroup} from "./PointGroup.ts";
import {releaseMesh} from "../../../framework/util.ts";

export class PointMesh extends PointGroup {

    normalMat: MeshBasicMaterial
    alertMat: MeshBasicMaterial

    lineCircles: Mesh[][]
    maxLines: number

    onFullCallback?: (m: Mesh[][])=>void
    constructor(width: number, height: number) {
        super(width, height)
        this.lineCircles = []
        this.maxLines = this.height

        this.normalMat = new MeshBasicMaterial({
            color: 0x0000ff,
            side: DoubleSide
        })
        this.alertMat = new MeshBasicMaterial({
            color: 0xff0000,
            side: DoubleSide
        })

    }

    addCircle(loc: Vector2, radius: number, category: number): Mesh {
        let geo = new CircleGeometry(0.2)
        let mat = this.getMaterial(category)
        let mesh = new Mesh(geo, mat)
        let realLoc = this.calcPosition(loc.x, loc.y)
        mesh.position.set(realLoc.x, realLoc.y, PointMesh.backgroundGap)
        let scale = radius/0.2
        mesh.scale.set(scale, scale, 1)
        mesh.userData['category'] = category
        this.add(mesh)
        return mesh
    }
    getMaterial(category: number): Material {
        let mat = this.normalMat// 默认
        switch (category) {
            case 1:
                mat = this.normalMat
                break
            case 9:
                mat = this.alertMat
                break
        }
        return mat
    }
    addCircleLine(items: CircleItem[]) {
        // 检查溢出多少行
        let buf: Mesh[][]= []
        let overflow = this.lineCircles.length+ 1 - this.maxLines
        if (overflow > 0) { // 取出溢出的多行
            // console.log('溢出', overflow, '行')
            for (let i = 0; i < overflow; i++) {
                let line = this.lineCircles.shift()
                buf.push(line!)
            }
            this.removeMesh(buf) // 在屏幕清除
        }
        for (let i = 0; i < this.lineCircles.length; i++) {
            let line = this.lineCircles[i]
            for (let j = 0; j < line.length; j++) {// 现有circle上移一行
                let circle = line[j]
                circle.position.setY(circle.position.y+1)
            }
        }
        let lineBuffer: Mesh[] = []
        for (let i = 0; i < items.length; i++) { // 添加新行
            // 增加新行
            let item = items[i]
            let mesh = this.addCircle(new Vector2(item.x, 0), item.radius,item.category)
            lineBuffer.push((mesh))
        }
        this.lineCircles.push(lineBuffer)// buffer里增加一行
        if (overflow > 0) {
            if (!this.onFullCallback) { // 内部处理
                this.releaseMesh(buf)
            } else {
                // 外部处理
                this.onFullCallback(buf)
            }
        }
    }

    calcPosition(x: number, y: number): Vector2 {
        let locX = -this.width/2+x
        let locY = -this.height/2+y
        return new Vector2(locX, locY)
    }

    releaseMesh(list: Mesh[][]) {
        for (let i = 0; i < list.length; i++) {
            // console.log('销毁第', i, '行圆形mesh')
            let line = list[i]
            for (let j = 0; j < line.length; j++) {
                let m = line[j]
                releaseMesh(m)
            }
        }
    }

    removeMesh(list: Mesh[][]) {
        // console.log("移除", list.length, '行')
        for (let i = 0; i < list.length; i++) {
            let line = list[i]
            for (let j = 0; j < line.length; j++) {
                let mesh = line[j]
                this.remove(mesh)
            }

        }
    }

    onFull(cb: (data: Mesh[][])=>void) {
        this.onFullCallback = cb
    }
}